Skip to content

Improve inference for truethy comparisons#5521

Open
staabm wants to merge 3 commits intophpstan:2.1.xfrom
staabm:impfinf
Open

Improve inference for truethy comparisons#5521
staabm wants to merge 3 commits intophpstan:2.1.xfrom
staabm:impfinf

Conversation

@staabm
Copy link
Copy Markdown
Contributor

@staabm staabm commented Apr 23, 2026

Apply truthy narrowing for function calls compared to truthy constants (TypeSpecifier)

  • When a function/method/static-call result is compared via === to a truthy constant (non-false, non-0, non-null, non-''), this implies the function returned non-false, enabling type-specifying extensions to narrow argument types
  • Limited to FuncCall, MethodCall, and StaticCall expressions to avoid interfering with other narrowing handlers (e.g., $object::class === 'Foo')
  • Before: strpos($s, ':') === 5$s stays as string
  • After: strpos($s, ':') === 5$s narrowed to non-falsy-string (via StrContainingTypeSpecifyingExtension)
  • Same improvement applies to mb_strpos, strrpos, stripos, strripos, and their mb_ variants

extracted from #5508

@staabm staabm requested a review from VincentLanglet April 23, 2026 14:14
)->setRootExpr($rootExpr));
}

if (
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Should the same be done with $context->false() && $constantType->toBoolean()->isFalse()->yes() ?

  2. Why only $exprNode instanceof FuncCall || $exprNode instanceof Expr\MethodCall || $exprNode instanceof Expr\StaticCall ? Shouldn't this be for every $exprNode ? Or at least NullsafeMethodCall (and so) too ?

I wonder if changing the two previous $constantType into $constantType->toBoolean doesnt give the same result...

Comment on lines +106 to +111
if (strpos($s, '0') == 0) { // 0|false
assertType('string', $s);
} else {
assertType('string', $s);
}
assertType('string', $s);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need a separate test with a function not specified further in StrContainingTypeSpecifyingExtension

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants